package com.onpositive.properties.editor.xml;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.onpositive.data.units.UnitKind;
import com.onpositive.properties.editor.model.DataContainer;
import com.onpositive.properties.editor.model.ParserData;
import com.onpositive.properties.editor.model.PropertyModel;
import com.onpositive.units.ParsedDimension;

public class Loader {

	public static DataContainer load(String path){
		
		File file = new File(path);
		if(!file.exists())
			return null;
		
		FileInputStream fis;
		try {
			fis = new FileInputStream(file);
			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(fis);
			Element element = doc.getDocumentElement();
			NodeList allProperties = element.getElementsByTagName("all-properties");
			
			ArrayList<PropertyModel> list = new ArrayList<PropertyModel>();
			int l = allProperties.getLength();
			for(int i = 0 ; i < l ; i++){
				Node node = allProperties.item(i);
				if(!(node instanceof Element))
					continue;
				
				Element el = (Element) node;
				NodeList pNodes = el.getElementsByTagName("property");
				
				for(int j = 0 ; j < pNodes.getLength() ; j++ ){
					Node n = pNodes.item(j);
					if(!(n instanceof Element))
						continue;
					
					Element e = (Element) n;
					PropertyModel pm = extractProperty(e);
					list.add(pm);
				}
			}
			DataContainer container = new DataContainer();
			container.setProperties(list);
			return container;
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
		
		return null;		
	}

	private static PropertyModel extractProperty(Element element) {
		
		String propertyName = element.getAttribute("name");
		NodeList parserNodes = element.getElementsByTagName("parser");
		int l = parserNodes.getLength();
		ArrayList<ParserData> list = new ArrayList<ParserData>();
		int count = 0 ;
		for( int i = 0 ; i < l; i++ ){
			Node node = parserNodes.item(i);
			if(!(node instanceof Element))
				continue;
			
			Element el = (Element) node;
			ArrayList<ParserData> pdList = extractParserData(el);
			list.addAll(pdList);
			for(ParserData pd : pdList)
				count+=pd.getCount();
		}
		PropertyModel pm = new PropertyModel();
		pm.setName(propertyName);
		pm.setParserDataArray(list);
		pm.setCount(count);
		return pm;
	}

	private static ArrayList<ParserData> extractParserData(Element element) {
		
		String id = element.getAttribute("id");
		 
		ArrayList<ParserData> list = new ArrayList<ParserData>();
		if(ParsedDimension.ID.equals(id)){
			NodeList unitList = element.getElementsByTagName("unit-kind");
			int length = unitList.getLength();
			for(int i = 0 ; i < length ; i++ ){
				Node node = unitList.item(i);
				if(!(node instanceof Element))
					continue;
				
				Element el = (Element) node;
				String countString = el.getAttribute("count");
				int count = Integer.parseInt(countString);
				String unitKindString = el.getAttribute("kind");
				UnitKind uk = UnitKind.valueOf(unitKindString);
				ParserData pd = new ParserData(id, count, uk);
				list.add(pd);
			}
		}
		else{
			String countString = element.getAttribute("count");
			int count = Integer.parseInt(countString);
			ParserData pd = new ParserData(id, count, null);
			list.add(pd);
		}
		return list;
	}
}
